home *** CD-ROM | disk | FTP | other *** search
- /*
- File: SuperFlyToolWindow.cp
-
- Contains: A tool palette with floating heads that follows the GDevice
- when it moves or resizes.
-
- Written by: Kent Miller
-
- Copyright: © 1996 Apple Computer
-
- Notes: Dave Falkenburg and I were talking about some behavior that
- some floating windows (like Control Strip) have when the display
- resizes. If the window ends up somewhere on an active screen,
- the Display Manager's default window moving code won't attempt to
- keep the window relative to its previous position.
-
- We think the behavior you really want is for the floating
- window to move to the position in the new graphics world
- relative to where it was in the old world. That is, if
- your Control Strip is in the bottom right of the display before
- the world changed, it should be on the bottom right of the same
- display in the new world. (Maybe it should follow the menu bar
- if it is on the main screen when the menu bar moves?)
-
- This file is meant to be a first crack at trying to be smart about
- the placement of a tool palette when the world changes. It will
- try to remain in the same place on the same device it was on when
- the devices get resized or rearranged.
-
- It exhibits weird behavior with the large tool palette when the
- screen changes sizes. Try it out with 2 displays turning mirroring
- on & off and see what I mean. How could this be made better?
-
- The Toolbar's WDEF is the Infinity Windoid by Troy Gaul. Email
- tgaul@halcyon.com for more information.
-
- Change History (most recent first):
-
- */
-
- #include <Displays.h>
- #include <Icons.h>
- #include <QDOffscreen.h>
-
-
- #include "Window.h"
- #include "SuperFly.h"
- #include "SuperFlyToolWindow.h"
-
- TSuperFlyToolWindow::TSuperFlyToolWindow()
- {
- this->CreateWindow(kFloatingWindow);
- }
-
- TSuperFlyToolWindow::~TSuperFlyToolWindow()
- {
- }
-
-
- void
- TSuperFlyToolWindow::Drag(Point startPoint)
- //I stole this from Window.cp in Sprocket and stripped out the part that
- //checked for window type since I know it's a floating window.
- {
- GrafPtr savePort;
- KeyMap theKeyMap;
- long dragResult;
- Boolean commandKeyDown = false;
-
- if (WaitMouseUp()) // de-bounce?
- {
- // Set up the Window Manager port.
-
- GetPort(&savePort);
- SetPort(gWindowManagerPort);
- SetClip(GetGrayRgn());
-
- // Check to see if the command key is down.
-
- GetKeys(theKeyMap);
- commandKeyDown = ((theKeyMap[1] & 0x8000) != 0);
-
- ClipAbove(FrontNormalWindow());
-
- // Drag an outline of the window around the desktop.
- // NOTE: DragGrayRgn destroys the region passed in, so make a copy
-
- RgnHandle tempRgn = NewRgn();
-
- GetWindowStructureRgn(fWindow, tempRgn);
- dragResult = DragGrayRgn(tempRgn, startPoint, &gDeskRectangle, &gDeskRectangle, noConstraint, nil);
-
- DisposeRgn(tempRgn);
-
- SetPort(savePort); // Get back to old port
-
- if ((dragResult != 0) && (dragResult != 0x80008000))
- this->Nudge((short) (dragResult & 0xFFFF),(short) (dragResult >> 16));
- }
-
- if (!commandKeyDown)
- this->Select();
-
- //The reason I overrode this method was so after I moved the toolbar, I could determine
- //which display the toolbar was on and save its rectangle.
- this->CalculateRelativePosition();
- }
-
- WindowPtr
- TSuperFlyToolWindow::MakeNewWindow(WindowPtr behindWindow)
- {
- Rect r;
- WindowPtr theWindow;
- GDHandle mainGD;
-
- SetRect(&r, 50,50,100,300);
-
- theWindow = this->GetNewWindow(1027, nil, behindWindow);
-
- if (theWindow != nil)
- {
- SetWTitle(theWindow, "\p");
- SizeWindow(theWindow, kToolButtonSize, (kToolButtonSize*kNumIcons)+3, true);
- ShowWindow(theWindow);
- mainGD = GetMainDevice();
- this->myStrucRect = (**((WindowPeek) theWindow)->strucRgn).rgnBBox;
- this->oldScreenRect = (**mainGD).gdRect;
- DMGetDisplayIDByGDevice(mainGD, &this->theID, false);
- }
- return(theWindow);
- }
-
-
- void
- TSuperFlyToolWindow::Draw(void)
- {
- RGBColor myGray = {0xCCCC,0xCCCC,0xCCCC};
- GrafPtr savePort;
- PicHandle thePicture;
- Rect theToolRect = {0, 0, 63, 63};
- SInt16 i;
-
- GetPort(&savePort);
- SetPort(this->fWindow);
-
- ForeColor(blackColor);
- BackColor(whiteColor);
-
- for(i=0; i<kNumIcons; i++)
- {
- thePicture = GetPicture(kIconBase+i);
- if (thePicture != nil)
- {
- DrawPicture(thePicture, &theToolRect);
- MoveTo( 0, ( (kToolButtonSize+1) *i)+kToolButtonSize +1);
- Line(kToolButtonSize,0);
- }
- OffsetRect(&theToolRect,0,kToolButtonSize+2);
- }
-
- SetPort(savePort);
-
- }
-
- void
- TSuperFlyToolWindow::Click(EventRecord * anEvent)
- //Not meant to be an example of how to to drag manager code
- {
- DragReference theDrag;
- Rect dragBounds;
- RgnHandle dragRgn;
- RgnHandle tempRgn;
- RgnHandle imageRgn;
-
- SInt16 whichHead;
- PicHandle theHead;
- GrafPtr savePort;
- UInt8 saveHState;
-
- theDrag = 0;
- dragRgn = nil;
- tempRgn = nil;
- imageRgn = nil;
- theHead = nil;
-
-
- if (!gHasDragManager)
- return;
-
- GetPort(&savePort);
- SetPort(this->fWindow);
-
- if (!WaitMouseMoved(anEvent->where))
- goto badExit;
-
- whichHead = (anEvent->where.v / (kToolButtonSize+1)); //zero based
- theHead = GetPicture(kIconBase+whichHead);
- if (theHead == nil)
- goto badExit;
-
- if (noErr != NewDrag(&theDrag))
- goto badExit;
-
- saveHState = HGetState((Handle) theHead);
- HLock((Handle) theHead);
- AddDragItemFlavor(theDrag, 1, 'PICT', *theHead, GetHandleSize((Handle)theHead), 0);
- HSetState((Handle) theHead, saveHState);
-
- //What is the Rect of this particular head?
- dragBounds.top = whichHead * (kToolButtonSize+1);
- dragBounds.bottom = dragBounds.top + kToolButtonSize;
- dragBounds.left = 0;
- dragBounds.right = kToolButtonSize;
- LocalToGlobal( (Point *) &dragBounds.top);
- LocalToGlobal( (Point *) &dragBounds.bottom);
- LocalToGlobal( (Point *) &anEvent->where);
-
- dragRgn = NewRgn();
- RectRgn(dragRgn, &dragBounds);
- tempRgn = NewRgn();
- CopyRgn(dragRgn, tempRgn);
- InsetRgn(tempRgn, 1, 1);
- DiffRgn(dragRgn, tempRgn, dragRgn);
-
- TrackDrag(theDrag, anEvent, dragRgn);
-
- GlobalToLocal( (Point *) &anEvent->where);
-
- badExit:
- SetPort( savePort);
- if (theHead) ReleaseResource( (Handle) theHead);
- if (theDrag) (void) DisposeDrag(theDrag);
- if (dragRgn) DisposeRgn(dragRgn);
- if (tempRgn) DisposeRgn(tempRgn);
- }
-
- Boolean
- TSuperFlyToolWindow::Close()
- {
- gMyToolWindow = nil;
- return TWindow::Close();
- }
-
-
- void
- TSuperFlyToolWindow::CalculateRelativePosition(void)
- {
- GDHandle bestGD, oldGD;
- WindowPeek windowAsWindowPeek = (WindowPeek) this->fWindow;
- Rect r;
-
- FindScreenRectWithLargestPartOfWindow(this->fWindow,&r,&bestGD);
- this->oldScreenRect = (**bestGD).gdRect;
- //Is my current position still on the display I was on? If so, then don't
- //change my stored ID. This is necessary when you turn mirroring off and on.
- //Since the Tool bar is on 2 GDevices, the tool bar could "hop" gdevices depending
- //on which one was first in the device list.
- DMGetGDeviceByDisplayID(this->theID, &oldGD, false);
- if (! SectRect(&(**oldGD).gdRect, &(**bestGD).gdRect, &r) )
- DMGetDisplayIDByGDevice(bestGD, &this->theID, false);
- this->myStrucRect = (**(windowAsWindowPeek)->strucRgn).rgnBBox;
- }
-
-
- void
- TSuperFlyToolWindow::MoveToRelativePosition(void)
- {
- GDHandle toolGD;
- WindowPeek windowAsWindowPeek = (WindowPeek) fWindow;
- SInt16 newH, newV, right, left, top, bottom, titleBarHeight, err;
-
- //Has the device I was on moved in global space or changed sizes?
- err = DMGetGDeviceByDisplayID(this->theID, &toolGD, false);
- if (err != noErr)
- {
- //my GDevice might have disappeared so I'll put the toolbar on the main device
- toolGD = GetMainDevice();
- this->theID = DMGetDisplayIDByGDevice(toolGD, &this->theID, false);
- }
-
- //How far was I from the right?
- right = oldScreenRect.right - this->myStrucRect.right;
- //Left?
- left = this->myStrucRect.left - oldScreenRect.left;
- //Top?
- top = this->myStrucRect.top - oldScreenRect.top;
- //Bottom?
- bottom = oldScreenRect.bottom - this->myStrucRect.bottom;
-
- PinAtZero(right);
- PinAtZero(left);
- PinAtZero(top);
- PinAtZero(bottom);
-
- //Was I closer to the left or right before?
- if (right < left)
- //If I was closer to the right, I want to hug the right
- newH = (**toolGD).gdRect.right - right - (this->myStrucRect.right - this->myStrucRect.left);
- else
- newH = (**toolGD).gdRect.left + left;
-
- //Was I closer to the top or bottom before?
- if (top < bottom)
- newV = (**toolGD).gdRect.top + top;
- else
- newV = (**toolGD).gdRect.bottom - bottom - (this->myStrucRect.bottom - this->myStrucRect.top);
-
- //Account for the title bar.
- titleBarHeight = (**windowAsWindowPeek->contRgn).rgnBBox.top - (**windowAsWindowPeek->strucRgn).rgnBBox.top;
- newV += titleBarHeight;
-
- //Would my new tool palette be behind the menu bar?
- if (TestDeviceAttribute(toolGD, mainScreen))
- {
- if ( newV < LMGetMBarHeight())
- newV += LMGetMBarHeight();
- }
-
- MoveWindow(this->fWindow, newH, newV, false);
- this->CalculateRelativePosition();
- }